/**
 * 文件:com.leimingtech.widget.ItemScroollListViewTouchListener.java
 *
 * 创建时间:2015-3-16
 *
 * 创建人:王磊杰
 */
package com.sxtyxt.widget;

import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.AbsListView;
import android.widget.ListView;

/**
 * 为ListView实现itemView滑动的Touch监听
 * 
 * @author 王磊杰
 * @created 2015-3-16
 */
public class ItemScroollListViewTouchListener implements View.OnTouchListener {

	private ListView listView;
	private int scroollViewId;

	private int slop;
	private long animationTime;
	private int viewWidth = -1;
	private float downX;
	private boolean isSwiping;
	private View downView;
	private static boolean isPaused;
	private int downViewPosition = -1;

	private int hiddenViewPosition = -1;
	private View hiddenView = null;

	private DismissListener dismissListener;

	public interface DismissListener {

		void onDismiss(ListView listView, int position, boolean dismissRight);

		void onUnDismiss(ListView listView, int position);
	}

	public ItemScroollListViewTouchListener(ListView listView,
	        int scroollViewId, DismissListener dismissListener) {
		ViewConfiguration vc = ViewConfiguration.get(listView.getContext());
		slop = vc.getScaledTouchSlop();
		this.listView = listView;
		animationTime = listView.getContext().getResources()
		        .getInteger(android.R.integer.config_shortAnimTime);
		this.scroollViewId = scroollViewId;
		this.dismissListener = dismissListener;
	}

	public void setHiddenView(View hiddenView, int position) {
		this.hiddenView = hiddenView;
		this.hiddenViewPosition = position;
	}

	public static void setEnabled(boolean enabled) {
		isPaused = !enabled;
	}

	public AbsListView.OnScrollListener makeScrollListener() {
		return new AbsListView.OnScrollListener() {
			@Override
			public void onScrollStateChanged(AbsListView absListView,
		            int scrollState) {
				setEnabled(
		                scrollState != AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
			}

			@Override
			public void onScroll(AbsListView absListView, int i, int i1,
		            int i2) {
			}
		};
	}

	@Override
	public boolean onTouch(View view, MotionEvent motionEvent) {

		switch (motionEvent.getActionMasked()) {
			case MotionEvent.ACTION_DOWN: {
				if (isPaused) {
					return false;
				}

				if (viewWidth < 0) {
					viewWidth = listView.getWidth();
				}

				Rect rect = new Rect();
				int childCount = listView.getChildCount();
				int[] listViewCoords = new int[2];
				listView.getLocationOnScreen(listViewCoords);
				int x = (int) motionEvent.getRawX() - listViewCoords[0];
				int y = (int) motionEvent.getRawY() - listViewCoords[1];
				View child;
				for (int i = 0; i < childCount; i++) {
					child = listView.getChildAt(i);
					child.getHitRect(rect);
					if (rect.contains(x, y)) {
						downView = child.findViewById(scroollViewId);
						break;
					}
				}

				if (downView != null
				        && downView.getVisibility() == View.VISIBLE) {
					downX = motionEvent.getRawX();
					downViewPosition = listView.getPositionForView(downView);
				}
				return false;
			}

			case MotionEvent.ACTION_UP: {
				if (isPaused) {
					return false;
				}
				float deltaX = motionEvent.getRawX() - downX;
				boolean dismiss = false;
				boolean dismissRight = false;
				if (Math.abs(deltaX) > viewWidth / 4) {
					dismiss = true;
					dismissRight = deltaX > 0;
				}

				if (hiddenViewPosition != -1 && hiddenView != null) {
					if (hiddenView != null) {

						hiddenView.animate().translationX(0).alpha(1)
						        .setDuration(animationTime).setListener(null);
					}

					setHiddenView(null, -1);
					dismissListener.onUnDismiss(listView, hiddenViewPosition);

				}

				if (downView != null
				        && downView.getVisibility() == View.VISIBLE)
					if (dismiss) {
						setHiddenView(downView, downViewPosition);
						dismissListener.onDismiss(listView, hiddenViewPosition,
						        dismissRight);
						downView.animate()
						        .translationX(
						                dismissRight ? viewWidth : -viewWidth)
						        .alpha(1).setDuration(animationTime)
						        .setListener(null);
					} else {

						downView.animate().translationX(0).alpha(1)
						        .setDuration(animationTime).setListener(null);
					}
				downX = 0;
				downView = null;
				isSwiping = false;
				break;
			}

			case MotionEvent.ACTION_MOVE: {
				if (isPaused) {
					return false;
				}
				float deltaX = motionEvent.getRawX() - downX;
				if (Math.abs(deltaX) > slop) {
					isSwiping = true;
					listView.requestDisallowInterceptTouchEvent(true);

					MotionEvent cancelEvent = MotionEvent.obtain(motionEvent);
					cancelEvent
					        .setAction(MotionEvent.ACTION_CANCEL | (motionEvent
					                .getActionIndex() << MotionEvent.ACTION_POINTER_INDEX_SHIFT));
					listView.onTouchEvent(cancelEvent);
					cancelEvent.recycle();
				}

				if (isSwiping && downView != null
				        && downView.getVisibility() == View.VISIBLE
				        && hiddenViewPosition != downViewPosition) {
					downView.setTranslationX(deltaX);
					return true;
				}
				break;
			}
		}
		return false;
	}

}
